﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Xml.Serialization;

using Microsoft.Xna.Framework;

namespace Spacer
{
	public class Galaxy
	{
		public Galaxy()
		{
			Name = "Galaxy";
			Systems = new SerializableDictionary<Guid,SolarSys>();
			SystemsGraph = new Tree<SolarSys>();
		}

		public Galaxy( Type generator ) {
			Name = "Galaxy";
			Systems = new SerializableDictionary<Guid,SolarSys>();
			SystemsGraph = new Tree<SolarSys>();

			// Generate the galaxy
            GalaxyGenerator gen = (GalaxyGenerator)Activator.CreateInstance( generator, this );
			gen.Generate();
		}

		// ----------

		public void PostLoad() {
			// Recreate system graph
			foreach(SolarSys sys in this.Systems.Values) {
				sys.Galaxy = this;
				if( sys.GalaxyNode == null )
					sys.GalaxyNode = new Tree<SolarSys>( sys );

				foreach(Guid id in sys.GalaxyNeighboringGuids) {
					SolarSys child = this.Systems[id];
					if( child.GalaxyNode == null )
						child.GalaxyNode = new Tree<SolarSys>( child );

					sys.GalaxyNode.AddChildNode( child.GalaxyNode );
				}

				sys.GalaxyNeighboringGuids = null;
			}

			// Set root
			this.SystemsGraph = this.Systems[this.RootSystemID].GalaxyNode;
			this.RootSystemID = new Guid();

			// Call PostLoad on the solar systems
			foreach( SolarSys sys in this.Systems.Values) {
				sys.PostLoad();
			}
		}

		// ----------

		public void ClearLoadCache() {
			foreach(SolarSys sys in Systems.Values) {
				sys.ClearLoadCache();
			}
		}

		// ----------
		
		public string Name { get; set; }
        public int Seed { get; set; }
		public Guid ID {
			get {
				return new Guid(
					Seed,
					0,
					0,
					new byte[8]
				);
			}
		}

		public SerializableDictionary<Guid,SolarSys> Systems { get; set; }

		[XmlIgnore] // This will be rebuilt by the save/load system
		public Tree<SolarSys> SystemsGraph { get; set; }
		
		// Saving and loading
		// This is only existant during a load which is why it generates and does not save
		private Guid m_RootSystemID;
		public Guid RootSystemID {
			get {
				if( m_RootSystemID != Guid.Empty )
					return m_RootSystemID;
				return SystemsGraph.Data.ID;
			}
			set { m_RootSystemID = value; }
		}
	}
}
